home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / oleo-1_4.lha / oleo-1.4 / lists.c < prev    next >
C/C++ Source or Header  |  1993-03-27  |  25KB  |  1,304 lines

  1. /*    Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This file is part of Oleo, the GNU Spreadsheet.
  4.  
  5. Oleo is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. Oleo is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with Oleo; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "funcdef.h"
  20.  
  21. #define obstack_chunk_alloc ck_malloc
  22. #define obstack_chunk_free free
  23. #include "obstack.h"
  24. #include "sysdef.h"
  25. #include "global.h"
  26. #include "cell.h"
  27. #include "ref.h"
  28. #include "window.h"
  29. #include "io-term.h"
  30. #include "io-abstract.h"
  31.  
  32. #define ROW_BUF 3
  33. #define COL_BUF 2
  34. #define MAX MAX_ROW
  35. #define MIN MIN_ROW
  36. static struct obstack find_stack;
  37.  
  38. #if 1
  39. #define malloc_chain_check(x)
  40. #endif
  41.  
  42. #ifdef __GNUC__
  43. #define inline __inline__
  44. #else
  45. #define inline
  46. #endif
  47.  
  48. #ifdef TEST_ME
  49. typedef unsigned char CELLREF;
  50. typedef unsigned int size_t;
  51. #define ck_malloc malloc
  52. extern void *malloc ();
  53. #define MIN 1
  54. #define MAX 65535
  55. #endif
  56.  
  57. struct list
  58. {
  59.   CELLREF lo, hi;
  60.   struct list *next;
  61.   char mem[1];
  62. };
  63.  
  64. struct find
  65. {
  66.   struct find *next;
  67.   CELLREF lo, hi, cur;
  68.   struct list **start;
  69.   struct list *curptr;
  70.   CELLREF left;
  71.   void *ret;
  72.   char fini;
  73.   int ele;
  74. };
  75.  
  76. struct find *finds = 0;
  77.  
  78. #ifdef __STDC__
  79. static inline void
  80. flush (struct list *ptr)
  81. #else
  82. static inline void
  83. flush (ptr)
  84.      struct list *ptr;
  85. #endif
  86. {
  87.   struct list *nxt;
  88.  
  89.   while (ptr)
  90.     {
  91.       nxt = ptr->next;
  92.       free (ptr);
  93.       ptr = nxt;
  94.     }
  95. }
  96.  
  97. #ifdef __STDC__
  98. static inline void
  99. resync (struct list *tofree, struct list *new, int ele)
  100. #else
  101. static inline void
  102. resync (tofree, new, ele)
  103.      struct list *tofree;
  104.      struct list *new;
  105.      int ele;
  106. #endif
  107. {
  108.   struct find *findp;
  109.  
  110.   if (ele == sizeof (struct cell)
  111.       && my_cell
  112.       && (char *) my_cell >= tofree->mem
  113.       && (char *) my_cell <= tofree->mem + ele * (1 + tofree->hi - tofree->lo))
  114.     my_cell = (struct cell *) (new->mem + ele * (cur_row - new->lo));
  115.  
  116.   for (findp = finds; findp; findp = findp->next)
  117.     {
  118.       if (tofree == findp->curptr)
  119.     {
  120.       CELLREF hi;
  121.       findp->curptr = new;
  122.       findp->ret = new->mem + (findp->cur - new->lo) * ele;
  123.       hi = (findp->hi < new->hi ? findp->hi : new->hi);
  124.       if (findp->cur < hi)
  125.         findp->left = hi - findp->cur;
  126.     }
  127.     }
  128.  
  129.   free (tofree);
  130. }
  131.  
  132. #ifdef __STDC__
  133. static inline void *
  134. find (CELLREF pos, struct list *ptr, int ele)
  135. #else
  136. static inline void *
  137. find (pos, ptr, ele)
  138.      CELLREF pos;
  139.      struct list *ptr;
  140.      int ele;
  141. #endif
  142. {
  143.   for (; ptr; ptr = ptr->next)
  144.     {
  145.       if (ptr->lo > pos)
  146.     break;
  147.       if (ptr->hi >= pos)
  148.     return ptr->mem + (pos - ptr->lo) * ele;
  149.     }
  150.   return 0;
  151. }
  152.  
  153. #ifdef __STDC__
  154. static inline void *
  155. make (CELLREF pos, struct list **prevp, int ele, int buf)
  156. #else
  157. static inline void *
  158. make (pos, prevp, ele, buf)
  159.      CELLREF pos;
  160.      struct list **prevp;
  161.      int ele;
  162.      int buf;
  163. #endif
  164. {
  165.   CELLREF lo, hi;
  166.   size_t size;
  167.   struct list *ptr;
  168.  
  169.   while (*prevp && (*prevp)->next && (*prevp)->next->lo < pos)
  170.     prevp = &((*prevp)->next);
  171.  
  172.   /* Was it easy? */
  173.   if (*prevp && (*prevp)->lo <= pos && (*prevp)->hi >= pos)
  174.     return (*prevp)->mem + (pos - (*prevp)->lo) * ele;
  175.  
  176.   lo = (pos < MIN + buf) ? MIN : pos - buf;
  177.   hi = (pos > MAX - buf) ? MAX : pos + buf;
  178.  
  179.   if (!*prevp
  180.       || ((*prevp)->hi < lo - 1
  181.       && (!(*prevp)->next
  182.           || (*prevp)->next->lo - 1 > hi)))
  183.     {
  184.       /* Allocate a whole new structure */
  185.       size = (1 + hi - lo) * ele;
  186.       ptr = ck_malloc (sizeof (struct list) + size);
  187.       ptr->lo = lo;
  188.       ptr->hi = hi;
  189.       if (*prevp && (*prevp)->hi < lo)
  190.     {
  191.       ptr->next = (*prevp)->next;
  192.       (*prevp)->next = ptr;
  193.     }
  194.       else
  195.     {
  196.       ptr->next = *prevp;
  197.       *prevp = ptr;
  198.     }
  199.       bzero (ptr->mem, size);
  200.       malloc_chain_check (1);
  201.     }
  202.   else if ((*prevp)->lo > lo)
  203.     {
  204.       /* Stretch one down a bit to fit */
  205.       hi = (*prevp)->hi;
  206.       size = (1 + hi - lo) * ele;
  207.       ptr = ck_malloc (sizeof (struct list) + size);
  208.       ptr->lo = lo;
  209.       ptr->hi = hi;
  210.       ptr->next = (*prevp)->next;
  211.       bcopy ((*prevp)->mem, ptr->mem + ((*prevp)->lo - ptr->lo) * ele, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  212.       bzero (ptr->mem, ((*prevp)->lo - ptr->lo) * ele);
  213.       resync (*prevp, ptr, ele);
  214.       *prevp = ptr;
  215.       malloc_chain_check (1);
  216.     }
  217.   else if ((*prevp)->hi < hi && (*prevp)->next && (*prevp)->next->lo <= hi)
  218.     {
  219.       /* Merge this one and the one after it */
  220.       size = (1 + (*prevp)->next->hi - (*prevp)->lo) * ele;
  221.       ptr = ck_malloc (sizeof (struct list) + size);
  222.       ptr->lo = (*prevp)->lo;
  223.       ptr->hi = (*prevp)->next->hi;
  224.       ptr->next = (*prevp)->next->next;
  225.       bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  226.       bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, ((*prevp)->next->lo - (*prevp)->hi) * ele);
  227.       bcopy ((*prevp)->next->mem,
  228.          ptr->mem + ((*prevp)->next->lo - ptr->lo) * ele,
  229.          (1 + (*prevp)->next->hi - (*prevp)->next->lo) * ele);
  230.       resync ((*prevp)->next, ptr, ele);
  231.       resync (*prevp, ptr, ele);
  232.       *prevp = ptr;
  233.       malloc_chain_check (1);
  234.     }
  235.   else if ((*prevp)->hi < hi)
  236.     {
  237.       /* stretch this one up a bit */
  238.       size = (1 + hi - (*prevp)->lo) * ele;
  239.       ptr = ck_malloc (sizeof (struct list) + size);
  240.       ptr->lo = (*prevp)->lo;
  241.       ptr->hi = hi;
  242.       ptr->next = (*prevp)->next;
  243.       bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  244.       bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, (hi - (*prevp)->hi) * ele);
  245.       resync (*prevp, ptr, ele);
  246.       *prevp = ptr;
  247.       malloc_chain_check (1);
  248.     }
  249.   else
  250.     ptr = *prevp;
  251. #ifdef TEST
  252.   if (ptr->lo > pos || ptr->hi < pos)
  253.     panic ("Make at %u not in %u %u", pos, ptr->lo, ptr->hi);
  254. #endif
  255.  
  256.   return ptr->mem + (pos - ptr->lo) * ele;
  257. }
  258.  
  259. #ifdef __STDC__
  260. static inline void *
  261. find_rng (struct list **start, CELLREF lo, CELLREF hi, int ele)
  262. #else
  263. static inline void *
  264. find_rng (start, lo, hi, ele)
  265.      struct list **start;
  266.      CELLREF lo;
  267.      CELLREF hi;
  268.      int ele;
  269. #endif
  270. {
  271.   struct list *ptr;
  272.   struct find *f;
  273.  
  274.   f = (struct find *)obstack_alloc (&find_stack, sizeof (struct find));
  275.   f->lo = lo;
  276.   f->hi = hi;
  277.   f->ele = ele;
  278.   f->start = start;
  279.   for (ptr = *start; ptr; ptr = ptr->next)
  280.     if (ptr->hi >= lo)
  281.       break;
  282.   if (ptr && ptr->lo <= hi)
  283.     {
  284.       f->cur = (ptr->lo > lo ? ptr->lo : lo);
  285.       f->curptr = ptr;
  286.       f->ret = ptr->mem + (f->cur - ptr->lo) * ele;
  287.       f->left = 1 + (f->hi < ptr->hi ? f->hi : ptr->hi) - f->cur;
  288.       f->fini = 0;
  289.     }
  290.   else
  291.     f->fini = 1;
  292.   f->next = finds;
  293.   finds = f;
  294.   return f;
  295. }
  296.  
  297. #ifdef __STDC__
  298. static inline void *
  299. make_rng (struct list **start, CELLREF lo, CELLREF hi, int ele, int buf)
  300. #else
  301. static inline void *
  302. make_rng (start, lo, hi, ele, buf)
  303.      struct list **start;
  304.      CELLREF lo;
  305.      CELLREF hi;
  306.      int ele;
  307.      int buf;
  308. #endif
  309. {
  310.   struct list **prevp;
  311.   struct list *ptr;
  312.   size_t size;
  313.   struct find *f;
  314.  
  315.   f = (struct find *)obstack_alloc (&find_stack, sizeof (struct find));
  316.   f->lo = f->cur = lo;
  317.   f->hi = hi;
  318.   f->left = 1 + hi - lo;
  319.   f->fini = 0;
  320.   f->ele = ele;
  321.   f->start = start;
  322.  
  323.   lo = lo <= MIN + buf ? MIN : lo - buf;
  324.   hi = hi >= MAX - buf ? MAX : hi + buf;
  325.  
  326.   for (prevp = start; *prevp && (*prevp)->hi < lo - 1; prevp = &((*prevp)->next))
  327.     ;
  328.   ptr = *prevp;
  329.   if (!*prevp || (*prevp)->lo - 1 > hi)
  330.     {
  331.       /* Allocate the whole thing */
  332.       size = (1 + hi - lo) * ele;
  333.       ptr = ck_malloc (sizeof (struct list) + size);
  334.       ptr->lo = lo;
  335.       ptr->hi = hi;
  336.       ptr->next = *prevp;
  337.       bzero (ptr->mem, size);
  338.       if (*prevp && (*prevp)->hi < lo)
  339.     {
  340.       ptr->next = (*prevp)->next;
  341.       (*prevp)->next = ptr;
  342.     }
  343.       else
  344.     {
  345.       ptr->next = *prevp;
  346.       *prevp = ptr;
  347.     }
  348.       *prevp = ptr;
  349.       malloc_chain_check (1);
  350.     }
  351.   else
  352.     {
  353.       if ((*prevp)->lo > lo)
  354.     {
  355.       /* Stretch this one down a bit */
  356.       size = (1 + (*prevp)->hi - lo) * ele;
  357.       ptr = ck_malloc (sizeof (struct list) + size);
  358.       ptr->lo = lo;
  359.       ptr->hi = (*prevp)->hi;
  360.       ptr->next = (*prevp)->next;
  361.       bcopy ((*prevp)->mem,
  362.          ptr->mem + ((*prevp)->lo - ptr->lo) * ele,
  363.          (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  364.       bzero (ptr->mem, ((*prevp)->lo - lo) * ele);
  365.       resync (*prevp, ptr, ele);
  366.       *prevp = ptr;
  367.       malloc_chain_check (1);
  368.     }
  369.       while ((*prevp)->hi < hi && (*prevp)->next && (*prevp)->next->lo <= hi)
  370.     {
  371.       /* Merge this one and the one after it */
  372.       /* Repeat as needed */
  373.       size = (1 + (*prevp)->next->hi - (*prevp)->lo) * ele;
  374.       ptr = ck_malloc (sizeof (struct list) + size);
  375.       ptr->lo = (*prevp)->lo;
  376.       ptr->hi = (*prevp)->next->hi;
  377.       ptr->next = (*prevp)->next->next;
  378.       bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  379.       bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, ((*prevp)->next->lo - (*prevp)->hi) * ele);
  380.       bcopy ((*prevp)->next->mem,
  381.          ptr->mem + ((*prevp)->next->lo - ptr->lo) * ele,
  382.          (1 + (*prevp)->next->hi - (*prevp)->next->lo) * ele);
  383.       resync ((*prevp)->next, ptr, ele);
  384.       resync (*prevp, ptr, ele);
  385.       *prevp = ptr;
  386.       malloc_chain_check (1);
  387.     }
  388.       if ((*prevp)->hi < hi)
  389.     {
  390.       /* stretch this one up a bit */
  391.       size = (1 + hi - (*prevp)->lo) * ele;
  392.       ptr = ck_malloc (sizeof (struct list) + size);
  393.       ptr->lo = (*prevp)->lo;
  394.       ptr->hi = hi;
  395.       ptr->next = (*prevp)->next;
  396.       bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
  397.       bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, (hi - (*prevp)->hi) * ele);
  398.       resync (*prevp, ptr, ele);
  399.       *prevp = ptr;
  400.       malloc_chain_check (1);
  401.     }
  402.     }
  403. #ifdef TEST
  404.   if (ptr->lo > f->lo || ptr->hi < f->hi)
  405.     panic ("Vector of %u-%u not big enough for %u-%u", (*prevp)->lo, (*prevp)->hi, f->lo, f->hi);
  406. #endif
  407.   f->curptr = ptr;
  408.   f->ret = ptr->mem + (f->cur - ptr->lo) * ele;
  409.   f->next = finds;
  410.   finds = f;
  411.   return f;
  412. }
  413.  
  414. #ifdef __STDC__
  415. static inline void *
  416. next_rng (struct find *f, CELLREF *posp)
  417. #else
  418. static inline void *
  419. next_rng (f, posp)
  420.      struct find *f;
  421.      CELLREF *posp;
  422. #endif
  423. {
  424.   void *ret;
  425.   struct find *next;
  426.  
  427.   if (!f)
  428.     return 0;
  429.   if (!f->fini)
  430.     {
  431.       if (f->left)
  432.     {
  433.       --(f->left);
  434.     fini:
  435.       if (posp)
  436.         *posp = f->cur;
  437.       f->cur++;
  438.       ret = f->ret;
  439.       f->ret = (char *) (f->ret) + f->ele;
  440.       return ret;
  441.     }
  442.       if (f->curptr->hi < f->hi)
  443.     {
  444.       f->curptr = f->curptr->next;
  445.       if (f->curptr && f->curptr->lo <= f->hi)
  446.         {
  447.           f->ret = f->curptr->mem;
  448.           f->left = (f->hi < f->curptr->hi ? f->hi : f->curptr->hi) - f->curptr->lo;
  449.           f->cur = f->curptr->lo;
  450.           goto fini;
  451.         }
  452.     }
  453.     }
  454.   next = f->next;
  455.   obstack_free (&find_stack, f);
  456.   finds = next;
  457.   return 0;
  458. }
  459.  
  460.  
  461. struct cf
  462.   {
  463.     struct cf *next;
  464.     struct find *rows, *cols;
  465.     int make;
  466.   };
  467.  
  468. static struct cf *fp;
  469. static struct list *the_cols;
  470.  
  471. static struct find *w_find;
  472. static struct find *h_find;
  473. static struct list *wids, *hgts;
  474.  
  475. void 
  476. init_cells ()
  477. {
  478.   obstack_begin (&find_stack, sizeof (struct find) * 15);
  479.   the_cols = 0;
  480.   wids = 0;
  481.   hgts = 0;
  482. }
  483.  
  484. #ifdef __STDC__
  485. void 
  486. flush_everything (void)
  487. #else
  488. void 
  489. flush_everything ()
  490. #endif
  491. {
  492.   struct list *ptr, *nxt;
  493.   int n;
  494.  
  495.   flush_variables ();
  496.   for (ptr = the_cols; ptr; ptr = nxt)
  497.     {
  498.       nxt = ptr->next;
  499.       for (n = 0; n <= ptr->hi - ptr->lo; n++)
  500.     flush (*(struct list **) (ptr->mem + (n * sizeof (struct list *))));
  501.       free (ptr);
  502.     }
  503.   the_cols = 0;
  504.   flush (wids);
  505.   wids = 0;
  506.   flush (hgts);
  507.   hgts = 0;
  508.   flush_fonts ();
  509. }
  510.  
  511. #if __STDC__
  512. struct cell *
  513. find_cell (CELLREF row, CELLREF col)
  514. #else
  515. struct cell *
  516. find_cell (row, col)
  517.      CELLREF row;
  518.      CELLREF col;
  519. #endif
  520. {
  521.   void **v;
  522.  
  523.   v = find (col, the_cols, sizeof (void *));
  524.   return v ? find (row, *v, sizeof (struct cell)) : 0;
  525. }
  526.  
  527. #if __STDC__
  528. struct cell *
  529. find_or_make_cell (CELLREF row, CELLREF col)
  530. #else
  531. struct cell *
  532. find_or_make_cell (row, col)
  533.      CELLREF row;
  534.      CELLREF col;
  535. #endif
  536. {
  537.   struct list **v;
  538.  
  539.   v = make (col, &the_cols, sizeof (struct list *), COL_BUF);
  540.   return make (row, v, sizeof (struct cell), ROW_BUF);
  541. }
  542.  
  543. #ifdef __STDC__
  544. void
  545. find_cells_in_range (struct rng *r)
  546. #else
  547. void
  548. find_cells_in_range (r)
  549.      struct rng *r;
  550. #endif
  551. {
  552.   struct cf *new;
  553.   struct list **firstcol;
  554.  
  555.   new = (struct cf *)obstack_alloc (&find_stack, sizeof (struct cf));
  556.   new->make = 0;
  557.   new->next = fp;
  558.   fp = new;
  559.   new->rows = find_rng (&the_cols, r->lc, r->hc, sizeof (void *));
  560.   firstcol = next_rng (new->rows, 0);
  561.   if (firstcol)
  562.     new->cols = find_rng (firstcol, r->lr, r->hr, sizeof (struct cell));
  563.   else
  564.     new->cols = 0;
  565. }
  566.  
  567. #ifdef __STDC__
  568. void
  569. make_cells_in_range (struct rng *r)
  570. #else
  571. void
  572. make_cells_in_range (r)
  573.      struct rng *r;
  574. #endif
  575. {
  576.   struct cf *new;
  577.   struct list **firstcol;
  578.  
  579.   new = (struct cf *)obstack_alloc (&find_stack, sizeof (struct cf));
  580.   new->make = 1;
  581.   new->next = fp;
  582.   fp = new;
  583.   new->rows = make_rng (&the_cols, r->lc, r->hc, sizeof (void *), ROW_BUF);
  584.   firstcol = next_rng (new->rows, 0);
  585.   new->cols = make_rng (firstcol, r->lr, r->hr, sizeof (struct cell), COL_BUF);
  586. }
  587.  
  588. #ifdef __STDC__
  589. struct cell *
  590. next_cell_in_range (void)
  591. #else
  592. struct cell *
  593. next_cell_in_range ()
  594. #endif
  595. {
  596.   struct cell *ret;
  597.   void *new_row;
  598.  
  599.   for (;;)
  600.     {
  601.       if (ret = next_rng (fp->cols, 0))
  602.     return ret;
  603.       new_row = next_rng (fp->rows, 0);
  604.       if (!new_row)
  605.     {
  606.       struct cf *old;
  607.  
  608.       old = fp->next;
  609.       obstack_free (&find_stack, fp);
  610.       fp = old;
  611.       return 0;
  612.     }
  613.       fp->cols = fp->make ? make_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell), ROW_BUF)
  614.       : find_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell));
  615.     }
  616. }
  617.  
  618. #ifdef __STDC__
  619. struct cell *
  620. next_row_col_in_range (CELLREF *rowp, CELLREF *colp)
  621. #else
  622. struct cell *
  623. next_row_col_in_range (rowp, colp)
  624.      CELLREF *rowp;
  625.      CELLREF *colp;
  626. #endif
  627. {
  628.   struct cell *ret;
  629.   struct list **new_row;
  630.  
  631.   for (;;)
  632.     {
  633.       if (ret = next_rng (fp->cols, rowp))
  634.     {
  635.       *colp = fp->rows->cur - 1;
  636.       return ret;
  637.     }
  638.       new_row = next_rng (fp->rows, colp);
  639.       if (!new_row)
  640.     {
  641.       struct cf *old;
  642.  
  643.       old = fp->next;
  644.       obstack_free (&find_stack, fp);
  645.       fp = old;
  646.       return 0;
  647.     }
  648.       fp->cols = fp->make ? make_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell), ROW_BUF)
  649.       : find_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell));
  650.     }
  651. }
  652.  
  653. #ifdef __STDC__
  654. void
  655. no_more_cells (void)
  656. #else
  657. void
  658. no_more_cells ()
  659. #endif
  660. {
  661.   struct cf *old;
  662.  
  663. /* This relies on knowing that the obstack contains
  664.  * the current find (struct cf) underneath two associated
  665.  * `struct find's.
  666.  * Here, we pop all those frames, and then free them at once.
  667.  */
  668.  
  669.   old = fp->next;
  670.   finds = finds->next->next;
  671.   obstack_free (&find_stack, fp);
  672.   fp = old;
  673. }
  674.  
  675. #ifdef __STDC__
  676. CELLREF
  677. max_row (CELLREF col)
  678. #else
  679. CELLREF
  680. max_row (col)
  681.      CELLREF col;
  682. #endif
  683. {
  684.   struct list **ptr;
  685.  
  686.   ptr = find (col, the_cols, sizeof (void *));
  687.   if (!ptr || !*ptr)
  688.     return MIN;
  689.   while ((*ptr)->next)
  690.     ptr = &((*ptr)->next);
  691.   return (*ptr)->hi;
  692. }
  693.  
  694. #ifdef __STDC__
  695. CELLREF
  696. max_col (CELLREF row)
  697. #else
  698. CELLREF
  699. max_col (row)
  700.      CELLREF row;
  701. #endif
  702. {
  703.   struct list *ptr;
  704.  
  705.   if (!the_cols)
  706.     return MIN;
  707.   for (ptr = the_cols; ptr->next; ptr = ptr->next)
  708.     ;
  709.   return ptr->hi;
  710. }
  711.  
  712. #ifdef __STDC__
  713. CELLREF 
  714. highest_row (void)
  715. #else
  716. CELLREF 
  717. highest_row ()
  718. #endif
  719. {
  720.   void *f;
  721.   struct list **ptr;
  722.   CELLREF hi = MIN;
  723.  
  724.   f = find_rng (&the_cols, MIN, MAX, sizeof (void *));
  725.   while (ptr = next_rng (f, 0))
  726.     {
  727.       if (*ptr)
  728.     {
  729.       while ((*ptr)->next)
  730.         ptr = &((*ptr)->next);
  731.       if ((*ptr)->hi > hi)
  732.         hi = (*ptr)->hi;
  733.     }
  734.     }
  735.   return hi;
  736. }
  737.  
  738.  
  739. #ifdef __STDC__
  740. CELLREF 
  741. highest_col (void)
  742. #else
  743. CELLREF 
  744. highest_col ()
  745. #endif
  746. {
  747.   struct list *ptr;
  748.  
  749.   if (!the_cols)
  750.     return MIN;
  751.   for (ptr = the_cols; ptr->next; ptr = ptr->next)
  752.     ;
  753.   return ptr->hi;
  754. }
  755.  
  756.  
  757. /* Routines for dealing with the widths of columns. . . */
  758.  
  759. #ifdef __STDC__
  760. int 
  761. get_width (CELLREF col)
  762. #else
  763. int 
  764. get_width (col)
  765.      CELLREF col;
  766. #endif
  767. {
  768.   int *ptr;
  769.  
  770.   ptr = find (col, wids, sizeof (int));
  771.   if (!ptr || !*ptr)
  772.     return default_width;
  773.   return (*ptr) - 1;
  774. }
  775.  
  776.  
  777. #ifdef __STDC__
  778. int 
  779. get_nodef_width (CELLREF col)
  780. #else
  781. int 
  782. get_nodef_width (col)
  783.      CELLREF col;
  784. #endif
  785. {
  786.   int *ptr;
  787.  
  788.   ptr = find (col, wids, sizeof (int));
  789.   return ptr ? *ptr : 0;
  790. }
  791.  
  792. #ifdef __STDC__
  793. void 
  794. set_width (CELLREF col, int wid)
  795. #else
  796. void 
  797. set_width (col, wid)
  798.      CELLREF col;
  799.      int wid;
  800. #endif
  801. {
  802.   int *ptr;
  803.  
  804.   ptr = make (col, &wids, sizeof (int), COL_BUF);
  805.   *ptr = wid;
  806. }
  807.  
  808. #ifdef __STDC__
  809. void 
  810. find_widths (CELLREF lo, CELLREF hi)
  811. #else
  812. void 
  813. find_widths (lo, hi)
  814.      CELLREF lo;
  815.      CELLREF hi;
  816. #endif
  817. {
  818.   w_find = find_rng (&wids, lo, hi, sizeof (int));
  819. }
  820.  
  821. #ifdef __STDC__
  822. int 
  823. next_width (CELLREF *posp)
  824. #else
  825. int 
  826. next_width (posp)
  827.      CELLREF *posp;
  828. #endif
  829. {
  830.   int *ptr;
  831.  
  832.   do
  833.     ptr = next_rng (w_find, posp);
  834.   while (ptr && !*ptr);
  835.   return ptr ? *ptr : 0;
  836. }
  837.  
  838. #ifdef __STDC__
  839. static void
  840. do_shift (int over, CELLREF lo, CELLREF hi, struct list **start, int buf)
  841. #else
  842. static void
  843. do_shift (over, lo, hi, start, buf)
  844.      int over;
  845.      CELLREF lo;
  846.      CELLREF hi;
  847.      struct list **start;
  848.      int buf;
  849. #endif
  850. {
  851.   CELLREF pos;
  852.   int w;
  853.   int *ptr;
  854.   int inc;
  855.   struct list *p;
  856.  
  857.   if (!*start)
  858.     return;
  859.   for (p = *start; p->next; p = p->next)
  860.     ;
  861.  
  862.   if (hi > p->hi)
  863.     hi = p->hi;
  864.  
  865.   if (over > 0)
  866.     {
  867.       pos = hi;
  868.       hi = lo;
  869.       lo = pos;
  870.       inc = -1;
  871.     }
  872.   else
  873.     inc = 1;
  874.  
  875.   if (inc > 0)
  876.     {
  877.       if (lo > hi)
  878.     return;
  879.     }
  880.   else if (hi > lo)
  881.     return;
  882.  
  883.   for (pos = lo;; pos += inc)
  884.     {
  885.       ptr = find (pos, *start, sizeof (int));
  886.       w = ptr ? *ptr : 0;
  887.       ptr = w ? make (pos + over, start, sizeof (int), buf) :
  888.         find (pos + over, *start, sizeof (int));
  889.       if (w || (ptr && *ptr))
  890.     *ptr = w;
  891.       if (pos == hi)
  892.     break;
  893.     }
  894.   for (pos = hi + over;;)
  895.     {
  896.       pos += inc;
  897.       ptr = find (pos, *start, sizeof (int));
  898.       if (ptr)
  899.     *ptr = 0;
  900.       if (pos == hi)
  901.     break;
  902.     }
  903. }
  904.  
  905. #ifdef __STDC__
  906. void 
  907. shift_widths (int over, CELLREF lo, CELLREF hi)
  908. #else
  909. void 
  910. shift_widths (over, lo, hi)
  911.      int over;
  912.      CELLREF lo;
  913.      CELLREF hi;
  914. #endif
  915. {
  916.   do_shift (over, lo, hi, &wids, COL_BUF);
  917. }
  918.  
  919.  
  920. /* This inserts lines in which formulas can be displayed. 
  921.  * It probably ought to be 1 or 0.
  922.  */
  923. int display_formula_mode = 0;
  924.  
  925. /* Routines for dealing with the height of rows 
  926.  */
  927. #ifdef __STDC__
  928. int 
  929. get_height (CELLREF row)
  930. #else
  931. int 
  932. get_height (row)
  933.      CELLREF row;
  934. #endif
  935. {
  936.   int *ptr;
  937.  
  938.   ptr = find (row, hgts, sizeof (int));
  939.   if (!ptr || !*ptr)
  940.     return default_height;
  941.   return *ptr - 1 + (display_formula_mode && using_curses);
  942. }
  943.  
  944. #ifdef __STDC__
  945. int 
  946. get_nodef_height (CELLREF row)
  947. #else
  948. int 
  949. get_nodef_height (row)
  950.      CELLREF row;
  951. #endif
  952. {
  953.   int *ptr;
  954.  
  955.   ptr = find (row, hgts, sizeof (int));
  956.   return ptr ? *ptr : 0;
  957. }
  958.  
  959. #ifdef __STDC__
  960. void 
  961. set_height (CELLREF row, int hgt)
  962. #else
  963. void 
  964. set_height (row, hgt)
  965.      CELLREF row;
  966.      int hgt;
  967. #endif
  968. {
  969.   int *ptr;
  970.  
  971.   ptr = make (row, &hgts, sizeof (int), ROW_BUF);
  972.   *ptr = hgt;
  973. }
  974.  
  975. float height_scale = 1.;
  976. float width_scale = 1.;
  977.  
  978. float user_height_scale = 1.;
  979. float user_width_scale = 1.;
  980.  
  981. #ifdef __STDC__
  982. void
  983. set_user_scales (double hs, double ws)
  984. #else
  985. void
  986. set_user_scales (hs, ws)
  987.      double hs;
  988.      double ws;
  989. #endif
  990. {
  991.   user_height_scale = hs;
  992.   user_width_scale = ws;
  993.   io_repaint ();
  994. }
  995.  
  996. #ifdef __STDC__
  997. int
  998. get_scaled_height (CELLREF r)
  999. #else
  1000. int
  1001. get_scaled_height (r)
  1002.      CELLREF r;
  1003. #endif
  1004. {
  1005.   return ((user_height_scale <= 0.)
  1006.       ? 1
  1007.       :  (int) (get_height (r) * height_scale * user_height_scale));
  1008. }
  1009.  
  1010. #ifdef __STDC__
  1011. int
  1012. get_scaled_width (CELLREF c)
  1013. #else
  1014. int
  1015. get_scaled_width (c)
  1016.      CELLREF c;
  1017. #endif
  1018. {
  1019.   return ((user_width_scale <= 0.)
  1020.       ? 1
  1021.       : (int)(get_width (c) * width_scale * user_width_scale));
  1022. }
  1023.  
  1024.  
  1025. #ifdef __STDC__
  1026. void 
  1027. find_heights (CELLREF lo, CELLREF hi)
  1028. #else
  1029. void 
  1030. find_heights (lo, hi)
  1031.      CELLREF lo;
  1032.      CELLREF hi;
  1033. #endif
  1034. {
  1035.   h_find = find_rng (&hgts, lo, hi, sizeof (int));
  1036. }
  1037.  
  1038. #ifdef __STDC__
  1039. int 
  1040. next_height (CELLREF *posp)
  1041. #else
  1042. int 
  1043. next_height (posp)
  1044.      CELLREF *posp;
  1045. #endif
  1046. {
  1047.   int *ptr;
  1048.  
  1049.   do
  1050.     ptr = next_rng (h_find, posp);
  1051.   while (ptr && !*ptr);
  1052.   return ptr ? *ptr : 0;
  1053. }
  1054.  
  1055. #ifdef __STDC__
  1056. void 
  1057. shift_heights (int dn, CELLREF lo, CELLREF hi)
  1058. #else
  1059. void 
  1060. shift_heights (dn, lo, hi)
  1061.      int dn;
  1062.      CELLREF lo;
  1063.      CELLREF hi;
  1064. #endif
  1065. {
  1066.   do_shift (dn, lo, hi, &hgts, ROW_BUF);
  1067. }
  1068.  
  1069. #ifdef TEST
  1070. extern char *bname[];
  1071.  
  1072. extern void dbg_print_ref_fm ();
  1073. extern void dbg_print_ref_to ();
  1074. extern void dbg_print_formula ();
  1075.  
  1076. void
  1077. dbg_print_cell (cp)
  1078.      CELL *cp;
  1079. {
  1080.   char *ptr1, *ptr2;
  1081.   char tmpbuf[30];
  1082.  
  1083.   switch (GET_TYP (cp))
  1084.     {
  1085.     case 0:
  1086.       ptr1 = "(null)";
  1087.       ptr2 = "";
  1088.       break;
  1089.     case TYP_FLT:
  1090.       sprintf (tmpbuf, "Float: %.16g", cp->cell_flt);
  1091.       ptr1 = tmpbuf;
  1092.       ptr2 = "";
  1093.       break;
  1094.     case TYP_INT:
  1095.       sprintf (tmpbuf, "Int: %ld", cp->cell_int);
  1096.       ptr1 = tmpbuf;
  1097.       ptr2 = "";
  1098.       break;
  1099.     case TYP_ERR:
  1100.       sprintf (tmpbuf, "Error: %d: ", cp->cell_err);
  1101.       ptr1 = tmpbuf;
  1102.       ptr2 = ename[cp->cell_err];
  1103.       break;
  1104.     case TYP_BOL:
  1105.       sprintf (tmpbuf, "Bool: %d: ", cp->cell_bol);
  1106.       ptr1 = tmpbuf;
  1107.       ptr2 = bname[cp->cell_bol];
  1108.       break;
  1109.     case TYP_STR:
  1110.       sprintf (tmpbuf, "String: %p: ", cp->cell_str);
  1111.       ptr1 = tmpbuf;
  1112.       ptr2 = cp->cell_str;
  1113.       break;
  1114.     default:
  1115.       sprintf (tmpbuf, "Unknown: %d", GET_TYP (cp));
  1116.       ptr1 = tmpbuf;
  1117.       ptr2 = "";
  1118.       break;
  1119.     }
  1120.   io_text_line ("    Cell %p:  flg %#lx  fm %p  to %p  fa %p  cy %d  val %s%s",
  1121.         cp, cp->cell_flags, cp->cell_refs_from, cp->cell_refs_to,
  1122.         cp->cell_formula, cp->cell_cycle, ptr1, ptr2);
  1123.   dbg_print_ref_fm (cp->cell_refs_from);
  1124.   dbg_print_ref_to (cp->cell_refs_to);
  1125.   dbg_print_formula (cp->cell_formula);
  1126. }
  1127.  
  1128.  
  1129. void 
  1130. dbg_print_list (ptr, ele, txt, prsub)
  1131.      struct list *ptr;
  1132.      int ele;
  1133.      char *txt;
  1134.      void (*prsub) ();
  1135. {
  1136.   CELLREF pos;
  1137.  
  1138.   while (ptr)
  1139.     {
  1140.       io_text_line ("%s %p: lo %u  hi %u  nxt %p  mem %p", txt, ptr, ptr->lo, ptr->hi, ptr->next, &(ptr->mem[0]));
  1141.       pos = ptr->lo;
  1142.       for (;;)
  1143.     {
  1144.       (*prsub) (ptr->mem + ele * (pos - ptr->lo));
  1145.       if (pos == ptr->hi)
  1146.         break;
  1147.       pos++;
  1148.     }
  1149.       ptr = ptr->next;
  1150.     }
  1151. }
  1152.  
  1153. static void 
  1154. dbg_pr_row (p)
  1155.      VOIDSTAR p;
  1156. {
  1157.   io_text_line ("  %p", p);
  1158. }
  1159.  
  1160. void 
  1161. dbg_print_rows (pos)
  1162.      CELLREF pos;
  1163. {
  1164.   dbg_print_list (the_cols, sizeof (struct list *), "row", dbg_pr_row);
  1165. }
  1166.  
  1167. static void 
  1168. dbg_pr_all (p)
  1169.      VOIDSTAR p;
  1170. {
  1171.   struct list **ptr;
  1172.  
  1173.   io_text_line ("  %p", p);
  1174.   ptr = p;
  1175.   dbg_print_list (*ptr, sizeof (struct cell), "  col",
  1176.             (void (*)(void *)) dbg_print_cell);
  1177. }
  1178.  
  1179. void 
  1180. dbg_print_array ()
  1181. {
  1182.   dbg_print_list (the_cols, sizeof (struct list *), "row", dbg_pr_all);
  1183. }
  1184.  
  1185. void 
  1186. dbg_print_cols (pos)
  1187.      CELLREF pos;
  1188. {
  1189.   /* struct list **ptr;
  1190.  
  1191.     ptr=find(...);
  1192.     if(...); */
  1193. }
  1194.  
  1195. #endif
  1196.  
  1197. #ifdef TEST_ME
  1198. main ()
  1199. {
  1200.   char buf[100];
  1201.   static void *vec[10];
  1202.   static siz[10];
  1203.   char *ret;
  1204.   int n;
  1205.   int t;
  1206.   int hi, lo;
  1207.   CELLREF pos;
  1208.   int z;
  1209.  
  1210.  
  1211.   while (printf ("-->"), gets (buf))
  1212.     {
  1213.       n = buf[1] - '0';
  1214.       switch (buf[0])
  1215.     {
  1216.     case 'i':
  1217.       if (sscanf (&buf[2], "%d %d", &siz[n], &t) < 1)
  1218.         {
  1219.           printf ("No size?\n");
  1220.           break;
  1221.         }
  1222.       vec[n] = list_init (siz[n], t);
  1223.       printf ("vec %d init'd to %lx with siz %u and buf %d\n", n, vec[n], siz[n], t);
  1224.       break;
  1225.  
  1226.     case 'f':
  1227.       ret = find (vec[n], atoi (&buf[2]));
  1228.       if (ret)
  1229.         {
  1230.           printf ("Found at %lx  ", ret);
  1231.           for (t = 0; t < siz[n]; t++)
  1232.         printf ("%x ", ret[t]);
  1233.           printf ("\n");
  1234.         }
  1235.       else
  1236.         printf ("Not found\n");
  1237.       break;
  1238.  
  1239.     case 'F':
  1240.       if (sscanf (&buf[2], "%d %d", &lo, &hi) != 2)
  1241.         {
  1242.           printf ("Faild to scan\n");
  1243.           break;
  1244.         }
  1245.       find_rng (vec[n], lo, hi);
  1246.       while (ret = next_rng (&pos))
  1247.         {
  1248.           printf ("Found %u at %lx  ", pos, ret);
  1249.           for (t = 0; t < siz[n]; t++)
  1250.         printf ("%x ", ret[t]);
  1251.           printf ("\n");
  1252.         }
  1253.       break;
  1254.  
  1255.     case 'm':
  1256.       ret = make (vec[n], atoi (&buf[2]));
  1257.       if (ret)
  1258.         {
  1259.           z = atoi (&buf[4]);
  1260.           printf ("Made at %lx  ", ret);
  1261.           for (t = 0; t < siz[n]; t++)
  1262.         {
  1263.           printf ("%x(%x) ", ret[t], z);
  1264.           ret[t] = z;
  1265.         }
  1266.           printf ("\n");
  1267.         }
  1268.       else
  1269.         printf ("Failed!!\n");
  1270.       break;
  1271.  
  1272.     case 'M':
  1273.       z = 0;
  1274.       if (sscanf (&buf[2], "%d %d %d", &lo, &hi, &z) < 2)
  1275.         {
  1276.           printf ("Scan failed\n");
  1277.           break;
  1278.         }
  1279.       make_rng (vec[n], lo, hi);
  1280.       while (ret = next_rng (&pos))
  1281.         {
  1282.           printf ("Found %u at %lx  ", pos, ret);
  1283.           for (t = 0; t < siz[n]; t++)
  1284.         {
  1285.           printf ("%x(%x) ", ret[t], z);
  1286.           ret[t] = z;
  1287.         }
  1288.           if (z)
  1289.         z++;
  1290.           printf ("\n");
  1291.         }
  1292.       break;
  1293.  
  1294.     case 'q':
  1295.       exit (0);
  1296.  
  1297.     default:
  1298.       printf ("Unknown command!\n");
  1299.     }
  1300.     }
  1301. }
  1302.  
  1303. #endif
  1304.